home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / das / subs.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  7KB  |  417 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  SUBS.C
  9.  *
  10.  */
  11.  
  12. #include "defs.h"
  13. #include <stdarg.h>
  14. #include <fcntl.h>
  15.  
  16. #ifndef O_BINARY
  17. #define O_BINARY    0
  18. #endif
  19.  
  20. Prototype char    *EAToString(EffAddr *);
  21. Prototype void    syntax(long);
  22. Prototype void    RegMaskToStr(char *, long);
  23. Prototype void    cvtstrtolower(char *);
  24. Prototype int    OnlyOneRegister(long);
  25. Prototype void    cerror(short, ...);
  26. Prototype long    Align(long, long);
  27. Prototype long    AlignDelta(long, long);
  28. Prototype char    *MakeTmpLabelName(void);
  29. Prototype char    ExtWordToReg(uword);
  30. Prototype char *ObtainErrorString(short);
  31. Prototype void NoMemory(void);
  32. Prototype void ExitError(short);
  33.  
  34. Prototype void eprintf(const char *ctl, ...);
  35. Prototype void veprintf(const char *ctl, va_list va);
  36. Prototype void eputc(char c);
  37.  
  38. Local char  *DumpRegs(char *, short, char, char);
  39.  
  40. char    *ErrorFileName = DCC "config/dice.errors";
  41. char    *ErrorAry;
  42. long    ErrorArySize;
  43. char    ErrBuf[128];
  44.  
  45. char *
  46. EAToString(ea)
  47. EffAddr *ea;
  48. {
  49.     static char Buf[2][128];
  50.     static int Bi;
  51.     char *ptr;
  52.     char rc = (ea->Reg1 >= RB_AREG) ? 'A' : 'D';
  53.  
  54.     Bi = !Bi;
  55.     ptr = Buf[Bi];
  56.  
  57.     if (ea->Mode1 == 0)
  58.     return("-");
  59.     switch(ea->Mode1) {
  60.     case AB_DN:
  61.     case AB_AN:
  62.     *ptr++ = rc;
  63.     *ptr++ = (ea->Reg1 & 7) + '0';
  64.     *ptr = 0;
  65.     break;
  66.     case AB_MMIND:
  67.     *ptr++ = '-';
  68.     case AB_INDAN:
  69.     case AB_INDPP:
  70.     *ptr++ = '(';
  71.     *ptr++ = rc;
  72.     *ptr++ = (ea->Reg1 & 7) + '0';
  73.     *ptr++ = ')';
  74.     *ptr = 0;
  75.     if (ea->Mode1 != AB_INDPP)
  76.         break;
  77.     *ptr++ = '+';
  78.     *ptr = 0;
  79.     break;
  80.     case AB_IMM:
  81.     *ptr++ = '#';
  82.     *ptr = 0;
  83.     case AB_ABSW:
  84.     case AB_ABSL:
  85.     case AB_OFFAN:
  86.     case AB_OFFIDX:
  87.     case AB_OFFPC:
  88.     case AB_OFFIDXPC:
  89.     case AB_BBRANCH:
  90.     case AB_WBRANCH:
  91.     if (ea->Label1) {
  92.         strcpy(ptr, ea->Label1->Name);
  93.         ptr += strlen(ptr);
  94.         if (ea->Offset1)
  95.         strcpy(ptr, "+");
  96.     }
  97.     if (ea->Offset1) {
  98.         sprintf(ptr, "%ld", ea->Offset1);
  99.         ptr += strlen(ptr);
  100.     }
  101.     switch(ea->Mode1) {
  102.     case AB_OFFAN:
  103.         sprintf(ptr, "(A%d)", ea->Reg1 - RB_AREG);
  104.         break;
  105.     case AB_OFFIDX:
  106.         {
  107.         short reg2 = ExtWordToReg(ea->ExtWord);
  108.         char x2 = (reg2 >= RB_AREG) ? 'A' : 'D';
  109.         char s2 = (ea->ExtWord & EXTF_LWORD) ? 'L' : 'W';
  110.  
  111.         sprintf(ptr, "(A%d,%c%d.%c)", ea->Reg1 - RB_AREG, x2, reg2 & 7, s2);
  112.         }
  113.         break;
  114.     case AB_OFFPC:
  115.         strcpy(ptr, "(PC)");
  116.         break;
  117.     case AB_OFFIDXPC:
  118.         {
  119.         short reg2 = ExtWordToReg(ea->ExtWord);
  120.         char x2 = (reg2 >= RB_AREG) ? 'A' : 'D';
  121.         char s2 = (ea->ExtWord & EXTF_LWORD) ? 'L' : 'W';
  122.  
  123.         sprintf(ptr, "(PC,%c%d.%c)", x2, reg2 & 7, s2);
  124.         }
  125.         break;
  126.     }
  127.     break;
  128.     case AB_REGS:
  129.     RegMaskToStr(ptr, ea->ExtWord);
  130.     break;
  131.     case AB_CCR:
  132.     strcpy(ptr, "CCR");
  133.     break;
  134.     case AB_SR:
  135.     strcpy(ptr, "SR");
  136.     break;
  137.     case AB_USP:
  138.     strcpy(ptr, "USP");
  139.     break;
  140.     default:
  141.     sprintf(ptr, "?%d", ea->Mode1);
  142.     break;
  143.     }
  144.     return(Buf[Bi]);
  145. }
  146.  
  147. void
  148. syntax(long n)
  149. {
  150.     cerror(EERROR_SYNTAX);
  151. }
  152.  
  153. char *
  154. DumpRegs(char *ptr, short rbefore, char rs, char re)
  155. {
  156.     char ac = (rs >= RB_AREG) ? 'A' : 'D';
  157.  
  158.     if (rbefore)
  159.     *ptr++ = '/';
  160.     if (rs < 0)
  161.     return(ptr);
  162.     if (rs == re) {
  163.     *ptr++ = ac;
  164.     *ptr++ = '0' + (rs & 7);
  165.     return(ptr);
  166.     }
  167.     *ptr++ = ac;
  168.     *ptr++ = '0' + (rs & 7);
  169.     *ptr++ = '-';
  170.     *ptr++ = ac;
  171.     *ptr++ = '0' + (re & 7);
  172.     return(ptr);
  173. }
  174.  
  175. void
  176. RegMaskToStr(ptr, mask)
  177. char *ptr;
  178. long mask;
  179. {
  180.     char *base = ptr;
  181.     short regno = -1;
  182.     short lastreg = -1;
  183.     short i;
  184.  
  185.     printf("mask %04lx\n", mask);
  186.     for (i = 0; i < 16; ++i) {
  187.     if (i == 8) {
  188.         ptr = DumpRegs(ptr, ptr != base, regno, lastreg);
  189.         regno = lastreg = -1;
  190.     }
  191.  
  192.     if (mask & (1 << i)) {
  193.         if (regno < 0) {
  194.         regno = lastreg = i;
  195.         } else {
  196.         if (lastreg == i - 1) {
  197.             lastreg = i;
  198.         } else {
  199.             ptr = DumpRegs(ptr, ptr != base, regno, lastreg);
  200.             regno = lastreg = i;
  201.         }
  202.         }
  203.     }
  204.     }
  205.     ptr = DumpRegs(ptr, ptr != base, regno, lastreg);
  206.     *ptr = 0;
  207. }
  208.  
  209. void
  210. cvtstrtolower(str)
  211. char *str;
  212. {
  213.     while (*str) {
  214.     if (*str >= 'A' && *str <= 'Z')
  215.         *str |= 0x20;
  216.     ++str;
  217.     }
  218. }
  219.  
  220.  
  221. /*
  222.  *  Returns the regno specified in the mask or -1 if more than one register
  223.  *  or no registers are specified.
  224.  */
  225.  
  226. int
  227. OnlyOneRegister(long mask)
  228. {
  229.     short i;
  230.  
  231.     for (i = 0; i < 16; ++i) {
  232.     if (mask & (1 << i)) {
  233.         mask &= ~(1 << i);
  234.         if (mask == 0)
  235.         return((int)i);
  236.         break;
  237.     }
  238.     }
  239.     return(-1);
  240. }
  241.  
  242. void
  243. cerror(short errorId, ...)
  244. {
  245.     static const char *MsgBase[] = {
  246.     "Error", "SoftError", "Warning", "Note", "Fatal", "FatalSoftError"
  247.     };
  248.     va_list va;
  249.  
  250.     if ((errorId & EF_MASK) != EF_VERBOSE) {
  251.         char *nm;
  252.         long line;
  253.  
  254.         nm = AsmFileName;
  255.         line = LineNo;
  256.  
  257.         if (DebugLineNo && (SrcFileName != NULL))
  258.         {
  259.            nm = SrcFileName;
  260.            line = DebugLineNo;
  261.         }
  262.     eprintf("DAS: \"%s\" L:%d %.*s%.*s:%d ", nm, line,
  263.             ((ErrorOpt == 2) ? 4 : 0), "C:0 ",
  264.         ((ErrorOpt == 2) ? 1 : (int)strlen(MsgBase[errorId >> 12])),
  265.         MsgBase[errorId >> 12],
  266.         errorId & 0x0FFF
  267.     );
  268.     }
  269.  
  270.     va_start(va, errorId);
  271.     veprintf(ObtainErrorString(errorId & 0x0FFF), va);
  272.     va_end(va);
  273.     eputc('\n');
  274.  
  275.     if ((errorId >> 12) >= __FATALPT__) {
  276.     ExitError(20);
  277.     }
  278.     switch(errorId & EF_MASK) {
  279.     case EF_WARN:
  280.     case EF_SOFTWARN:
  281.     if (ExitCode < 5)
  282.         ExitCode = 5;
  283.     break;
  284.     case EF_ERROR:
  285.     if (ExitCode < 20)
  286.         ExitCode = 20;
  287.     break;
  288.     }
  289. }
  290.  
  291. void
  292. ExitError(short code)
  293. {
  294.     if (Fo)
  295.     fclose(Fo);
  296.     if (FoName)
  297.     remove(FoName);
  298.     if (ExitCode < code)
  299.     ExitCode = code;
  300.     exit(ExitCode);
  301. }
  302.  
  303. long
  304. Align(offset, align)
  305. long offset;
  306. long align;
  307. {
  308.     long n;
  309.  
  310.     n = offset & (align - 1);
  311.     if (n)
  312.     n = align - n;
  313.     return(offset + n);
  314. }
  315.  
  316. long
  317. AlignDelta(offset, align)
  318. long offset;
  319. long align;
  320. {
  321.     long n = offset & (align - 1);
  322.     if (n)
  323.     n = align - n;
  324.     return(n);
  325. }
  326.  
  327. char *
  328. MakeTmpLabelName()
  329. {
  330.     static long id;
  331.     char *buf = malloc(16);
  332.  
  333.     if (buf == NULL)
  334.     NoMemory();
  335.     sprintf(buf, "&$%ld", id++);
  336.     return(buf);
  337. }
  338.  
  339. void
  340. NoMemory()
  341. {
  342.     eprintf("NO MEMORY!\n");
  343.     ExitError(25);
  344. }
  345.  
  346. void
  347. eprintf(const char *ctl, ...)
  348. {
  349.     va_list va;
  350.  
  351.     va_start(va, ctl);
  352.     veprintf(ctl, va);
  353.     va_end(va);
  354. }
  355.  
  356. void
  357. veprintf(const char *ctl, va_list va)
  358. {
  359.     vfprintf(stderr, ctl, va);
  360.     if (ErrorFi)
  361.     vfprintf(ErrorFi, ctl, va);
  362. }
  363.  
  364. void
  365. eputc(char c)
  366. {
  367.     fputc(c, stderr);
  368.     if (ErrorFi)
  369.     fputc(c, ErrorFi);
  370. }
  371.  
  372. char
  373. ExtWordToReg(uword extword)
  374. {
  375.     if (extword & EXTF_AREG)
  376.     return(((extword >> 12) & 7) + RB_AREG);
  377.     return((extword >> 12) & 7);
  378. }
  379.  
  380. char *
  381. ObtainErrorString(short errNum)
  382. {
  383.     short i;
  384.  
  385.     if (ErrorAry == NULL) {
  386.     int fd;
  387.     short siz;
  388.  
  389.     if ((fd = open(ErrorFileName, O_RDONLY|O_BINARY)) < 0) {
  390.         sprintf(ErrBuf, "(can't open %s!)", ErrorFileName);
  391.         return(ErrBuf);
  392.     }
  393.     siz = lseek(fd, 0L, 2);
  394.     lseek(fd, 0L, 0);
  395.     ErrorAry = malloc(siz + 1);
  396.     read(fd, ErrorAry, siz);
  397.     close(fd);
  398.     {
  399.         char *ptr;
  400.         for (ptr = strchr(ErrorAry, '\n'); ptr; ptr = strchr(ptr + 1, '\n'))
  401.         *ptr = 0;
  402.     }
  403.     ErrorAry[siz] = 0;
  404.     ErrorArySize = siz;
  405.     }
  406.     for (i = 0; i < ErrorArySize; i += strlen(ErrorAry + i) + 1) {
  407.     char *ptr;
  408.     if (ErrorAry[i] == 'A' && ErrorAry[i+1] == 'S' && strtol(ErrorAry + i + 3, &ptr, 10) == errNum)
  409.         return(ptr + 1);
  410.     }
  411.     sprintf(ErrBuf, "(no entry in %s for error)", ErrorFileName);
  412.     return(ErrBuf);
  413. }
  414.  
  415.  
  416.  
  417.